<template>
  <div class="main">
    <div id="cesiumContainer"></div>
  </div>
</template>

<script>
var Cesium = require("cesium/Cesium");
import "../../../node_modules/cesium/Source/Widgets/widgets.css";
import $ from "jquery"
export default {
  name:"Map",
  data() {
    return {
      viewer: "",
      position: "",
      center: "",
      reBbox : {//大余县外接矩形的Bbox
        minx: 114.00029582000024,
        miny: 25.256412020000132,
        maxx: 114.68747202800001,
        maxy: 25.623771009999994,
      },
      extend:{},//屏幕可视范围的东西南北
      length:"",//切分出来的每个小网格的高
      cameraHeight: "", //相机的高度
      width:"",//切分出来的每个小网格的宽
      removeKey:[],
    };
  },
  mounted() {
    var that = this;
    Cesium.Ion.defaultAccessToken =
      "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI4MTFmZTI3MC1hZTE0LTRmYzctYTIwMy1lMjQ1ZjgxMGRhM2UiLCJpZCI6NzI4ODQsImlhdCI6MTYzNjQ0MjcyNH0.i6q-HiknfKeuLMD-rMBZ751jBnSCzqC0nHtDpZkaBu0";
      // WebMapServiceImageryProvider
      // ArcGisMapServerImageryProvider
    let maplayer = new Cesium.ArcGisMapServerImageryProvider({
      url: "https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer",
      
    });
    this.viewer = new Cesium.Viewer("cesiumContainer", {
      animation: false, //是否显示动画插件
      shouldAnimation: false, //是否自动显示动画（下方时间轴是不是在走着）
      homeButton: false, //是否显示home按钮
      fullscreenButton: false, // 是否显示全屏按钮
      baseLayerPicker: false, // 是否显示图层选择控件
      geocoder: false, // 是否显示地名查找控件
      timeline: false, // 是否显示时间线控件
      sceneModePicker: false, // 是否显示投影方式控件（右上角的小圆球）
      navigationHelpButton: false, // 是否显示帮助信息控件
      infoBox: false, // 是否显示点击要素之后显示的信息
      sceneMode: 3, // 初始场景模式 1 2D模式 2 2D循环模式 3 3D模式  Cesium.SceneMode
      selectionIndicator: false, //选中指示框
      navigationInstructionsInitiallyVisible: false, // 帮助按钮，初始化的时候是否展开
      mapProjection: new Cesium.WebMercatorProjection(), //地图投影体系
      terrainProvider: Cesium.createWorldTerrain(), //地形图层提供者，仅baseLayerPicker设为false有意义
      contextOptions: {
        webgl: {
          alpha: true,
          depth: true,
          stencil: true,
          antialias: true,
          premultipliedAlpha: true,
          //通过canvas.toDataURL()实现截图需要将该项设置为true
          preserveDrawingBuffer: true,
          failIfMajorPerformanceCaveat: true,
        },
      },
    });
    this.viewer.scene.imageryLayers.addImageryProvider(maplayer); //去除谷歌请求
    // this.viewer.imageryLayers.addImageryProvider(annLayer); //图层类型的添加
    this.viewer.imageryLayers.get(0).show = true; //添加图层
    this.viewer._cesiumWidget._creditContainer.style.display = "none"; // 去除版权信息
    // this.viewer.scene.globe.depthTestAgainstTerrain = true; //地形遮挡(深度监测)
    this.viewer.scene.globe.enableLighting = false; //是否使用地球光照
    this.viewer.scene.globe.showGroundAtmosphere = false; //绘制在地球上的地面大气。
    this.viewer.terrainProvider = Cesium.createWorldTerrain({
      //启用地形照明和水体效果
      requestWaterMask: true,
      requestVertexNormals: true,
    });
    this.viewer.camera.flyTo({
      destination: Cesium.Cartesian3.fromDegrees(114.352497, 25.401622, 1500),
      orientation: {
        heading: Cesium.Math.toRadians(0.0),
        pitch: Cesium.Math.toRadians(-90.0),
        roll: Cesium.Math.toRadians(0.0),
      },
      duration: 5, //飞行时间value
    });
    this.addListener();
    // 将大余县外接矩形x,y,方向各切分500次，并给切分得到的每个小网格赋予相应的编号
    this.length = (that.reBbox.maxy - that.reBbox.miny) / 300;//每个小网格的高
    this.width = (that.reBbox.maxx - that.reBbox.minx) / 300;//每个小网格的
  },
  methods: {
    addListener() {
      var dataMap = new Map()
      var that = this
      var url2 = "http://112.94.21.83:25015/geoserver/cite/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=cite%3Adayu_building_merge1&outputFormat=application%2Fjson";
      var bl=0//记录移动的次数
      // that.viewer.camera.changed.addEventListener(function(){//监听相机移动
      // this.viewer.scene.postRender.addEventListener(function(){//实时监听地图
      that.viewer.scene.camera.moveEnd.addEventListener(function(){//相机移动结束开始加载
      that.startHandler()
        let remove = []//当前可视范围内所有网格的编号
        that.cameraHeight = that.viewer.camera.positionCartographic.height
        console.log(that.cameraHeight)
        if(that.cameraHeight<2500){
          // 获取可视范围
          var rectangle = {};
          that.extend = that.viewer.camera.computeViewRectangle(); //可视范围
          rectangle.minx = Cesium.Math.toDegrees(that.extend.west);
          rectangle.miny = Cesium.Math.toDegrees(that.extend.south);
          rectangle.maxx = Cesium.Math.toDegrees(that.extend.east);
          rectangle.maxy = Cesium.Math.toDegrees(that.extend.north);

          // 计算得到屏幕范围左上角的点所在网格的信息
          let dxl = Math.abs(that.reBbox.minx - rectangle.minx)//外接矩形的minx到可视范围的minx的距离
          let dyl = Math.abs(that.reBbox.maxy - rectangle.maxy)//外接矩形的maxy到可视范围的maxy的距离
          // x方向：//Math.ceil：向上取整、Math.floor：向下取整
          let dxKey = Math.floor(dxl / that.width)//左上角横向(向下取整)
          // y方向：
          let dyKey = Math.floor(dyl / that.length)//左上角纵向(向下取整)
          // console.log(dxKey,dyKey)
          if(dxKey<10){
            var a = "00"+dxKey
          }else if(dxKey<100){
            var a = "0"+dxKey
          }else if(dxKey<1000){
            var a = dxKey
          }
          if(dyKey<10){
            var b = "00"+dyKey
          }else if(dyKey<100){
            var b = "0"+dyKey
          }else if(dyKey<1000){
            var b = dyKey
          }
          let Bboxlt={}
          Bboxlt.key = a+""+b
          Bboxlt.minx = that.reBbox.minx + dxKey *that.width
          Bboxlt.maxx = that.reBbox.minx + (dxKey +1) *that.width
          Bboxlt.miny = that.reBbox.maxy - (dyKey + 1) * that.length
          Bboxlt.maxy = that.reBbox.maxy - dyKey * that.length
          // console.log(Bboxlt)

          // 计算得到屏幕范围右下角的点所在网格的信息
          let dxr = Math.abs(that.reBbox.minx - rectangle.maxx)//外接矩形的minx到可视范围的maxx的距离
          let dyr = Math.abs(that.reBbox.maxy -  rectangle.miny)//外接矩形的maxy到可视范围的miny的距离
          let dxKeyr = Math.floor(dxr / that.width)//x方向
          let dyKeyr = Math.floor(dyr / that.length)//y方向
          if(dxKeyr<10){
            var ar = "00"+dxKeyr
          }else if(dxKeyr<100){
            var ar = "0"+dxKeyr
          }else if(dxKeyr<1000){
            var ar = dxKeyr
          }
          if(dyKeyr<10){
            var br = "00"+dyKeyr
          }else if(dyKeyr<100){
            var br = "0"+dyKeyr
          }else if(dyKeyr<1000){
            var br = dyKeyr
          }
          let Bboxrb={}
          Bboxrb.key = ar+""+br
          Bboxrb.minx = that.reBbox.minx + dxKeyr *that.width
          Bboxrb.maxx = that.reBbox.minx + (dxKeyr +1) *that.width
          Bboxrb.miny = that.reBbox.maxy - (dyKeyr + 1) * that.length
          Bboxrb.maxy = that.reBbox.maxy - dyKeyr * that.length
          // if(bl==0){//第一次进来没有移动时加载
            for(var k=0;k<=(dxKeyr - dxKey);k++){//从左到右
              let bboxNew = {}
              bboxNew.minx = Bboxlt.minx + k*that.width
              bboxNew.maxx = bboxNew.minx + that.width
              var key1 = dxKey + k
              if(key1<10){
                var a1 = "00"+key1
              }else if(key1<100){
                var a1 = "0"+key1
              }else if(key1<1000){
                var a1 = key1
              }
              for(var j=0;j<=(dyKeyr - dyKey);j++){//由上到下
              // console.log("1")
                var object = {}
                var id = []
                bboxNew.miny = Bboxlt.miny - j*that.length
                bboxNew.maxy = bboxNew.miny+that.length
                var bbox2 = bboxNew.minx+","+bboxNew.miny+","+bboxNew.maxx+","+bboxNew.maxy
                // console.log(that.juxBbox[j])
                var key2 = dyKey + j
                if(key2<10){
                  var b1 = "00"+key2
                }else if(key2<100){
                  var b1 = "0"+key2
                }else if(key2<1000){
                  var b1 = key2
                }
                bboxNew.key = a1+""+b1
                // console.log(bboxNew.key)
                remove.push(bboxNew.key)
                // axios.get(url2, {params: {bbox: bbox2,},}).then((res) =>{})
                if(that.removeKey.indexOf(bboxNew.key)==-1){
                  $.ajax({
                    url:url2,
                    data:{
                      bbox:bbox2
                    },
                    async:false,//设置请求为同步请求
                    type:"get",
                    success:function(res){
                      var datasource2 = Cesium.GeoJsonDataSource.load(res);
                      datasource2.then(function(source){
                        if(that.viewer.dataSources._dataSources.length>0){//去重
                        // xlArray:存储与当前网格相邻的八个网格的信息
                        // console.log(bboxNew.key)
                        // 计算相邻八个网格的编号
                          var leftTop = (a1-1)+""+(b1-1)//左上
                          var top = a1+""+(b1-1)//正上
                          var rightTop = (a1+1)+""+(b1-1)//右上
                          var left = (a1-1)+""+b1//左
                          var right = (a1+1)+""+b1//右
                          var leftBtm = (a1-1)+""+(b1+1)//左下
                          var bottom = a1+""+(b1+1)//下
                          var rightBtm = (a1+1)+""+(b1+1)//右下
                          let xlArray = [leftTop,top,rightTop,left,right,leftBtm,bottom,rightBtm]
                          // console.log(xlArray)
                          for(var xl=0;xl<xlArray.length;xl++){
                            let dataValue = dataMap.get(xlArray[xl])
                            if(dataValue!=undefined){
                              for(var d4=0;d4<source.entities.values.length;d4++){
                                if(dataValue.indexOf(source.entities.values[d4]._id)!=-1){
                                  source.entities.values.splice(d4,1)
                                  d4 = d4-1
                                  // console.log(dataValue)
                                }
                              }
                            }
                          }
                        }
                        // 实体对象的id：source.entities.values[c]._id
                        for(var c=0;c<source.entities.values.length;c++){
                          id.push(source.entities.values[c]._id)
                        }
                        object.arrayId = id
                        source._name = bboxNew.key
                        that.viewer.dataSources.add(source)
                      })
                    }
                  })
                  object.key = bboxNew.key
                  that.removeKey.push(bboxNew.key)
                  dataMap.set(object.key,object.arrayId)//map:(key,value)
                  // console.log(dataMap)
                  // bboxOld = bboxNew
                }
              }
            }
            // 卸载
            var _dataSources = that.viewer.dataSources._dataSources
            if(bl>0){//移动之后
              for(var a4=0;a4<that.removeKey.length;a4++){
                if(remove.indexOf(that.removeKey[a4])==-1){
                  var valueId = dataMap.get(that.removeKey[a4])
                  if(valueId!=undefined){
                    for(var i1=0;i1<_dataSources.length;i1++){
                      if(that.removeKey[a4]==_dataSources[i1]._name){
                        // console.log("执行了")
                        that.viewer.dataSources.remove(_dataSources[i1])
                      }
                    }
                  }
                  dataMap.delete(that.removeKey[a4])
                  that.removeKey.splice(a4,1)
                  a4 = a4 - 1
                }
              }
            }
            
          // }
        }
        // console.log("移动了"+bl+"次")
        bl++
        // console.log(that.removeKey)
        // console.log(that.array)
        // console.log(dataMap)
        // console.log(remove)
        // console.log(that.viewer.dataSources)
        // that.endHandler()
      })
    },
  },
};
</script>

<style>
head {
  height: 0;
  margin: 0;
}
html,
body,
#app,
.main,
#cesiumContainer {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  overflow: hidden;
  font-family: sans-serif;
}
</style>